iT邦幫忙

2024 iThome 鐵人賽

DAY 17
0

Odoo ORM 支援某些 SQL 功能,如視圖 (Views)、索引 (Indexes)、事務 (Transactions)、資料完整性 (Data Integrity)、資料安全性 (Data Security),以及某些層次的子查詢 (Subqueries)。這些功能在 Odoo 中的實現方式略有不同,以下是詳細的介紹:

Odoo ORM 和 SQL 進階功能比較

功能 Odoo ORM SQL
View (視圖) 透過 compute fields 或模型模擬視圖 SQL 原生支持 View
Data Integrity (資料完整性) 透過 _sql_constraints 和欄位屬性 透過約束和索引保障資料完整性
Data Security (資料安全性) 使用存取權限和記錄規則進行控管 使用 SQL 用戶權限和 GRANT/REVOKE
Subqueries (子查詢) 限制於 ORM 層次,複雜查詢需撰寫 SQL SQL 支援任意複雜度的子查詢

View (視圖)

Odoo ORM 中並沒有直接支持 SQL 視圖的概念。然而,可以透過自訂模型來模擬視圖的效果。Odoo 中可以使用 @api.depends 或計算欄位 (compute fields) 來動態生成計算結果,類似於視圖的概念。

  • 模擬 SQL View:
    • 你可以創建一個只讀模型,並使用 compute 方法來生成結果。
class ResPartnerInvoicing(models.Model):
    _name = 'res.partner.invoicing'
    _description = 'Invoicing Report'
    
    partner_id = fields.Many2one('res.partner')
    total_invoiced = fields.Float(compute='_compute_total_invoiced')
    
    @api.depends('partner_id')
    def _compute_total_invoiced(self):
        for record in self:
            record.total_invoiced = sum(record.partner_id.invoice_ids.mapped('amount_total'))

Transactions

Odoo 使用 PostgreSQL 作為資料庫,並內建支援 SQL 事務。ORM 操作是在事務內進行的,這意味著當操作失敗時,可以自動回滾。在 Odoo 中,每個請求 (request) 都是在一個事務中執行的。

手動控制事務: Odoo 自動處理事務,但你也可以通過 cr (cursor) 來手動控制事務,例如:

from odoo import api, SUPERUSER_ID

@api.model
def process_transaction(self):
    cr = self.env.cr
    try:
        # 一些 ORM 操作
        cr.commit()  # 提交事務
    except Exception:
        cr.rollback()  # 回滾事務
  1. Data Integrity (資料完整性)
    Odoo 提供多種方式來保證資料的完整性,尤其是透過 _sql_constraints 來建立資料庫級別的唯一性約束和檢查條件。這些約束可以幫助防止資料不一致或不正確的輸入。

SQL 約束:

class ResPartner(models.Model):
    _inherit = 'res.partner'
    
    _sql_constraints = [
        ('check_credit_limit', 'CHECK(credit_limit >= 0)', 'Credit limit must be positive')
    ]

此外,Odoo 還支援 required、unique 等欄位屬性,來加強資料完整性。

  1. Data Security (資料安全性)
    Odoo 提供了非常靈活且細粒度的安全性控制,透過使用「存取權限」(Access Control) 和「記錄規則」(Record Rules) 來確保資料的安全性。

存取權限 (Access Control): 存取權限允許設定不同的模型操作權限,例如 read、write、create 和 unlink,分別對應查詢、更新、創建和刪除操作。

記錄規則 (Record Rules): 記錄規則可設定細粒度的資料訪問權限,基於使用者或群組的不同,來動態決定誰可以存取哪些記錄。

<record id="partner_rule" model="ir.rule">
    <field name="name">Partner rule</field>
    <field name="model_id" ref="model_res_partner"/>
    <field name="domain_force">[('user_id', '=', user.id)]</field>
    <field name="groups" eval="[(4, ref('group_user'))]"/>
</record>
  1. Subqueries (子查詢)
    Odoo ORM 沒有原生支援複雜的 SQL 子查詢,但你可以透過使用 search 方法進行多層查詢,或者在需要時撰寫自定義 SQL 查詢。

ORM 層級的查詢: Odoo 的查詢方法能模擬一些簡單的子查詢,像是用 search 找到一組記錄,然後基於這些記錄進行進一步的查詢。

查詢 John Doe 的所有銷售訂單

partner = env['res.partner'].search([('name', '=', 'John Doe')])
orders = env['sale.order'].search([('partner_id', '=', partner.id)])

原生 SQL 查詢: 如果需要更複雜的子查詢,可以直接撰寫 SQL 語句,並使用 env.cr 來執行。

self.env.cr.execute("""
    SELECT * FROM sale_order
    WHERE partner_id IN (SELECT id FROM res_partner WHERE name = 'John Doe')
""")

Odoo ORM 和 SQL 進階功能比較

功能 Odoo ORM SQL
View (視圖) 透過 compute fields 或模型模擬視圖 SQL 原生支持 View
Data Integrity (資料完整性) 透過 _sql_constraints 和欄位屬性 透過約束和索引保障資料完整性
Data Security (資料安全性) 使用存取權限和記錄規則進行控管 使用 SQL 用戶權限和 GRANT/REVOKE
Subqueries (子查詢) 限制於 ORM 層次,複雜查詢需撰寫 SQL SQL 支援任意複雜度的子查詢

結論

Odoo ORM 支援許多 SQL 的核心功能,並且透過抽象層的優勢,讓開發者能以更簡潔的方式操作資料庫。然而,對於需要複雜查詢、視圖等功能的場合,可能需要手動撰寫 SQL 查詢來補充 ORM 的功能。這種靈活性讓 Odoo 成為一個強大且易於擴展的 ERP 平台,能夠滿足大多數商業應用中的資料庫需求。


上一篇
【Day16】Odoo ORM 資料操作,簡易電商顧客訂單 增刪查改 (CRUD) 及 複雜關聯查詢 (Join)
下一篇
【Day18】透過 JSON 和 字典 (Dictionary) 來解釋 XML格式語法
系列文
30天就算 0 基礎,也能使用 GenAI 創造簡單的 Odoo 模組應用21
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言